#ifndef _SYS_FUNC_H_
#define _SYS_FUNC_H_

#include "FanObj.h"
#include "SysTypes.h"

#define FUNC_VTABLE(self)   ((FuncVTable*)((FanObj*)self)->vtable)


extern Type*    Func_classType;
extern VTable*  Func_classVTable;


/* [sys::Func] Attributes */
struct Func
{
  FanObj        super;
};


/* [sys::Func] Virtual-table */
typedef struct FuncVTable
{
  FanObjVTable  super;
  Val           (*call_0)(Func* self);
  Val           (*call_1)(Func* self, Val a);
  Val           (*call_2)(Func* self, Val a, Val b);
  Val           (*call_3)(Func* self, Val a, Val b, Val c);
  Val           (*call_4)(Func* self, Val a, Val b, Val c, Val d);
  Val           (*call_5)(Func* self, Val a, Val b, Val c, Val d, Val e);
  Val           (*call_6)(Func* self, Val a, Val b, Val c, Val d, Val e, Val f);
  Val           (*call_7)(Func* self, Val a, Val b, Val c, Val d, Val e, Val f, Val g);
  Val           (*call)(Func* self, Val a, Val b, Val c, Val d, Val e, Val f, Val g, Val h);
  Val           (*callList)(Func* self, List* args);
  Val           (*callOn)(Func* self, NullableObj target, List* args);
} FuncVTable;


/* [sys::Func] Methods and fields */
Type*           Func_returns(Func* self);
Int             Func_arity(Func* self);
List*           Func_params(Func* self);
Method*         Func_method(Func* self);
Val             Func_callList(Func* self, List* args);
Val             Func_callOn(Func* self, NullableObj target, List* args);
Val             Func_call_0(Func* self);
Val             Func_call_1(Func* self, Val a);
Val             Func_call_2(Func* self, Val a, Val b);
Val             Func_call_3(Func* self, Val a, Val b, Val c);
Val             Func_call_4(Func* self, Val a, Val b, Val c, Val d);
Val             Func_call_5(Func* self, Val a, Val b, Val c, Val d, Val e);
Val             Func_call_6(Func* self, Val a, Val b, Val c, Val d, Val e, Val f);
Val             Func_call_7(Func* self, Val a, Val b, Val c, Val d, Val e, Val f, Val g);
Val             Func_call(Func* self, Val a, Val b, Val c, Val d, Val e, Val f, Val g, Val h);
Func*           Func_bind(Func* self, List* args);
Func*           Func_retype(Func* self, Type* t);


/* [sys::Func] Type-system functions */
Type*           Func_initType(void);
VTable*         Func_initVTable(void);
void            Func_initStatic(void);


#endif
